package org.kongqian.user.service.impl;

import org.kongqian.basic.utils.VerifyCodeUtils;
import org.kongqian.user.domain.Logininfo;
import org.kongqian.user.dto.VerifyCodeDTO;
import org.kongqian.user.mapper.LogininfoMapper;
import org.kongqian.user.service.IVerifyCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;


@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Override
    public String getImageVerifyCode(String key) {
        //生成随机验证码
        String code = VerifyCodeUtils.generateVerifyCode(4);
        //将随机验证码存到redis中 key前面拼接运用场景
        redisTemplate.opsForValue().set("image_verify_code_"+key,code,5, TimeUnit.MINUTES);
        //合并图片生成图形验证码
        String verifyCode = null;
        try {
            verifyCode = VerifyCodeUtils.VerifyCode(100, 40, code);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //返回
        return verifyCode;
    }

    @Override
    public void sendSmsCode(VerifyCodeDTO dto) {
        //参数校验 手机号 图形验证码 查看手机号是否已经注册
        if (StringUtils.isEmpty(dto.getImageCode())){
            throw new RuntimeException("图形验证码错误！");
        }
        if (StringUtils.isEmpty(dto.getMobile())){
            throw new RuntimeException("手机号错误！");
        }
        if (StringUtils.isEmpty(dto.getImageCodeKey())){
            throw new RuntimeException("请重新获取图形验证码！");
        }
        //判断图形验证码是否正确
        Object imageVerifyCode = redisTemplate.opsForValue().get(dto.getImageCodeKey());
        if (!Objects.nonNull(imageVerifyCode)){
            throw new RuntimeException("输入的图形验证码已过期,请重新输入！");
        }
        if (!dto.getImageCode().equalsIgnoreCase(imageVerifyCode.toString())){
            throw new RuntimeException("输入的图形验证码错误,请重新输入！");
        }
        //判断手机号是否已经注册过了
        Logininfo logininfo=logininfoMapper.selectByMobile(dto.getMobile());
        if (Objects.nonNull(logininfo)){
            throw new RuntimeException("该手机号已注册！");
        }
        //判断手机号的验证码是否存在
        String key=dto.getMobile();
        String textingCode =(String) redisTemplate.opsForValue().get("verify_code_texting" + key);
        //存在 就判断是否已经过了一分钟时间
        String codeStr =null;
        if (!StringUtils.isEmpty(textingCode)) {
            //重发时间：过了就发已经有的验证码，并重置验证码的过期时间
            String timeStr = textingCode.split(":")[1];
            if (System.currentTimeMillis()-Long.parseLong(timeStr)>60*1000){
                codeStr = textingCode.split(":")[0];
            }else {
                //没过就提示已经发过了，请在60秒否再发
                throw new RuntimeException("请在60秒后再发送短信！");
            }
        }
        //不存在就生成验证码 并设置过期时间，key=应用场景+前端生成的key value=验证码:发送时间
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        redisTemplate.opsForValue()
                .set("verify_code_texting" + key,verifyCode+":"+System.currentTimeMillis(),5 ,TimeUnit.MINUTES);
        //发短信
        System.out.println("你的验证码为："+verifyCode+",请在3分钟内使用！");
//        SmsUtil.sendSms(dto.getMobile(), "你的验证码为："+verifyCode+",请在3分钟内使用！");
    }

    @Override
    public void wechatBindSendSmsCode(VerifyCodeDTO dto) {
        //参数的非空校验
        if (StringUtils.isEmpty(dto.getMobile())){
            throw new RuntimeException("手机号错误！");
        }

        //判断手机号的验证码是否存在
        String key=dto.getMobile();
        String textingCode =(String) redisTemplate.opsForValue().get("bind_code_texting" + key);
        //存在 就判断是否已经过了一分钟时间
        String codeStr =null;
        if (!StringUtils.isEmpty(textingCode)) {
            //重发时间：过了就发已经有的验证码，并重置验证码的过期时间
            String timeStr = textingCode.split(":")[1];
            if (System.currentTimeMillis()-Long.parseLong(timeStr)>60*1000){
                codeStr = textingCode.split(":")[0];
            }else {
                //没过就提示已经发过了，请在60秒否再发
                throw new RuntimeException("请在60秒后再发送短信！");
            }
        }
        //不存在就生成验证码 并设置过期时间，key=应用场景+前端生成的key value=验证码:发送时间
        codeStr = VerifyCodeUtils.generateVerifyCode(4);
        redisTemplate.opsForValue()
                .set("bind_code_texting" + key,codeStr+":"+System.currentTimeMillis(),5 ,TimeUnit.MINUTES);
        //发短信
        System.out.println("你的验证码为："+codeStr+",请在3分钟内使用！");
    }
}
